package com.jt.aop;

import com.jt.annotation.CacheFind;
import com.jt.util.ObjectMapperUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.ShardedJedis;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * @author Cx
 * @stage JT Of Fourth stage
 * @creat 2020-12-08 16:26
 */
@Aspect
@Component
public class CacheAop {

    @Autowired
    // private Jedis jedis; 单台测试
    // private ShardedJedis jedis; // 分片redis
    // private JedisSentinelPool sentinelPool;
    private JedisCluster jedis;

    @Around("@annotation(cacheFind)")
    public Object around(ProceedingJoinPoint joinPoint, CacheFind cacheFind) {
        // Jedis jedis = sentinelPool.getResource();
        Object result = null;
        String key = cacheFind.key();
        String argString = Arrays.toString(joinPoint.getArgs());
        key = key + "::" + argString;
        try {
            if (jedis.exists(key)) {
                String json = jedis.get(key);
                MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
                result = ObjectMapperUtil.toObject(json, methodSignature.getReturnType());
            } else {
                result = joinPoint.proceed();
                String json = ObjectMapperUtil.toJson(result);
                if (cacheFind.seconds() > 0) {
                    jedis.setex(key, cacheFind.seconds(), json);
                } else {
                    jedis.set(key, json);
                }
            }
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            throw new RuntimeException(throwable);
        }
        // jedis.close();
        return result;
    }

    // @Pointcut("bean(itemCatServiceImpl)")
    // @Pointcut("within(com.jt.service.*)")
/*    @Pointcut("execution(* com.jt.service..*.*(..))")
    public void pointCut() {
    }

    @Before("pointCut()")
    public void before(JoinPoint joinPoint) {
        // 获取目标对象
        Object target = joinPoint.getTarget();
        System.out.println("target = " + target);
        // 获取目标对象的路径 包名.类名
        String className = joinPoint.getSignature().getDeclaringTypeName();
        String methodName = joinPoint.getSignature().getName();
        System.out.println("目标方法的路径: " + (className + "." + methodName));
        // 获取参数类型
        System.out.println(Arrays.toString(joinPoint.getArgs()));
    }

    @Around("pointCut()")
    public Object around(ProceedingJoinPoint joinPoint) {
        Object data = null;
        try {
            data = joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return data;
    }*/

}
